import { ApiDocumentation, ApiEndpoint, ApiParameter, ApiExample } from '../extension';

export class MarkdownExporter {
  export(documentation: ApiDocumentation): string {
    let markdown = this.generateHeader(documentation);
    markdown += this.generateTableOfContents(documentation);
    markdown += this.generateSummary(documentation);
    markdown += this.generateEndpoints(documentation);
    markdown += this.generateFooter(documentation);
    
    return markdown;
  }

  private generateHeader(documentation: ApiDocumentation): string {
    return `# API Documentation

**Project**: ${documentation.projectName}
**Description**: ${documentation.projectDescription}
**Generated**: ${documentation.generatedAt.toLocaleString()}

---

`;
  }

  private generateTableOfContents(documentation: ApiDocumentation): string {
    let toc = '## Table of Contents\n\n';
    
    if (documentation.endpoints.length > 0) {
      toc += '### Endpoints\n\n';
      documentation.endpoints.forEach((endpoint, index) => {
        const method = endpoint.method || 'GET';
        const path = endpoint.path || '/';
        toc += `${index + 1}. [${method} ${path}](#${this.sanitizeAnchor(endpoint.name)})\n`;
      });
    }
    
    toc += '\n---\n\n';
    return toc;
  }

  private generateSummary(documentation: ApiDocumentation): string {
    const totalEndpoints = documentation.endpoints.length;
    const methods = this.getMethodCounts(documentation.endpoints);
    
    let summary = '## Summary\n\n';
    summary += `- **Total Endpoints**: ${totalEndpoints}\n`;
    summary += `- **Project**: ${documentation.projectName}\n`;
    summary += `- **Generated**: ${documentation.generatedAt.toLocaleString()}\n\n`;
    
    if (Object.keys(methods).length > 0) {
      summary += '### HTTP Methods\n\n';
      Object.entries(methods).forEach(([method, count]) => {
        summary += `- **${method}**: ${count} endpoints\n`;
      });
      summary += '\n';
    }
    
    summary += '---\n\n';
    return summary;
  }

  private generateEndpoints(documentation: ApiDocumentation): string {
    if (documentation.endpoints.length === 0) {
      return '## Endpoints\n\nNo API endpoints found in the project.\n\n';
    }

    let endpoints = '## Endpoints\n\n';
    
    documentation.endpoints.forEach((endpoint, index) => {
      endpoints += this.generateEndpointSection(endpoint, index + 1);
    });
    
    return endpoints;
  }

  private generateEndpointSection(endpoint: ApiEndpoint, index: number): string {
    const method = endpoint.method || 'GET';
    const path = endpoint.path || '/';
    const methodColor = this.getMethodColor(method);
    
    let section = `### ${index}. ${endpoint.name}\n\n`;
    section += `**${method}** \`${path}\`\n\n`;
    section += `**Description**: ${endpoint.description}\n\n`;
    section += `**File**: \`${endpoint.filePath}:${endpoint.lineNumber}\`\n\n`;
    section += `**Return Type**: \`${endpoint.returnType}\`\n\n`;
    
    if (endpoint.parameters.length > 0) {
      section += this.generateParametersTable(endpoint.parameters);
    }
    
    if (endpoint.examples.length > 0) {
      section += this.generateExamplesSection(endpoint.examples);
    }
    
    section += '\n---\n\n';
    return section;
  }

  private generateParametersTable(parameters: ApiParameter[]): string {
    let table = '#### Parameters\n\n';
    
    // Group parameters by source
    const pathParams = parameters.filter(p => p.source === 'path');
    const queryParams = parameters.filter(p => p.source === 'query');
    const bodyParams = parameters.filter(p => p.source === 'body');
    const headerParams = parameters.filter(p => p.source === 'header');
    const otherParams = parameters.filter(p => !p.source || !['path', 'query', 'body', 'header'].includes(p.source));

    // Generate tables for each parameter type
    if (pathParams.length > 0) {
      table += this.generateParameterGroupTable('Path Parameters', pathParams);
    }
    
    if (queryParams.length > 0) {
      table += this.generateParameterGroupTable('Query Parameters', queryParams);
    }
    
    if (headerParams.length > 0) {
      table += this.generateParameterGroupTable('Headers', headerParams);
    }
    
    if (bodyParams.length > 0) {
      table += this.generateParameterGroupTable('Request Body', bodyParams);
    }
    
    if (otherParams.length > 0) {
      table += this.generateParameterGroupTable('Other Parameters', otherParams);
    }
    
    table += '\n';
    return table;
  }

  private generateParameterGroupTable(title: string, parameters: ApiParameter[]): string {
    let table = `**${title}**\n\n`;
    table += '| Name | Type | Required | Default | Description |\n';
    table += '|------|------|----------|---------|-------------|\n';
    
    parameters.forEach(param => {
      const required = param.required ? 'Yes' : 'No';
      const defaultValue = param.defaultValue || '-';
      const description = param.description || `Parameter ${param.name}`;
      
      table += `| ${param.name} | \`${param.type}\` | ${required} | ${defaultValue} | ${description} |\n`;
    });
    
    table += '\n';
    return table;
  }

  private generateExamplesSection(examples: ApiExample[]): string {
    let section = '#### Examples\n\n';
    
    examples.forEach(example => {
      section += `**${example.title}**\n\n`;
      section += `${example.description}\n\n`;
      section += `\`\`\`${example.language}\n${example.code}\n\`\`\`\n\n`;
    });
    
    return section;
  }

  private generateFooter(documentation: ApiDocumentation): string {
    return `---

## Footer

This documentation was automatically generated by the API Documentation Generator VSCode extension.

**Generated from**: ${documentation.endpoints.length} files
**Total endpoints**: ${documentation.endpoints.length}

---
`;
  }

  private getMethodCounts(endpoints: ApiEndpoint[]): Record<string, number> {
    const counts: Record<string, number> = {};
    
    endpoints.forEach(endpoint => {
      const method = endpoint.method || 'GET';
      counts[method] = (counts[method] || 0) + 1;
    });
    
    return counts;
  }

  private getMethodColor(method: string): string {
    const colors: Record<string, string> = {
      'GET': '🟢',
      'POST': '🔵',
      'PUT': '🟡',
      'DELETE': '🔴',
      'PATCH': '🟠'
    };
    
    return colors[method] || '⚪';
  }

  private sanitizeAnchor(text: string): string {
    return text
      .toLowerCase()
      .replace(/[^a-z0-9\s-]/g, '')
      .replace(/\s+/g, '-')
      .replace(/-+/g, '-')
      .trim();
  }
} 